package com.aces2win.server.entities;

import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Set;

import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.aces2win.shared.beans.QuoteBean;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

@PersistenceCapable
public class Quote {
	
	@PrimaryKey
    private Key key;
	@Persistent
	private	Ticker	ticker;
	@Persistent
	private	Date	quoteDate;
	@Persistent
	private	double	open;
	@Persistent
	private	double	high;
	@Persistent
	private	double	low;
	@Persistent
	private	double	close;
	@Persistent
	private	long	volume;
	@Persistent
	private	double	adjRatio;
	
	public Quote(Date d, double o, double h, double l, double c, long v, double adj){
		this.quoteDate = d;
		this.open = o;
		this.high = h;
		this.low = l;
		this.close = c;
		this.volume = v;
		this.adjRatio = adj;
	}
	public Quote(String t,Date d){
		this.key =KeyFactory.stringToKey(t+d);
		//this.ticker = new Ticker(t);
	}
	public Quote(double close, Date d){
		this.setClose(close);
		this.setQuoteDate(d);
	}
	
	public Key getKey() {
		return key;
	}
	public void setKey(Key key) {
		this.key = key;
	}
	public Ticker getTicker() {
		return ticker;
	}
	public void setTicker(Ticker ticker) {
		this.ticker = ticker;
	}
	public Date getQuoteDate() {
		return quoteDate;
	}
	public void setQuoteDate(Date quoteDate) {
		this.quoteDate = quoteDate;
	}
	public double getOpen() {
		return open;
	}
	public void setOpen(double open) {
		this.open = open;
	}
	public double getHigh() {
		return high;
	}
	public void setHigh(double high) {
		this.high = high;
	}
	public double getLow() {
		return low;
	}
	public void setLow(double low) {
		this.low = low;
	}
	public double getClose() {
		return close;
	}
	public void setClose(double close) {
		this.close = close;
	}
	public long getVolume() {
		return volume;
	}
	public void setVolume(long volume) {
		this.volume = volume;
	}
	public double getAdjRatio() {
		return adjRatio;
	}
	public void setAdjRatio(double adjRatio) {
		this.adjRatio = adjRatio;
	}
	
	public static ArrayList<QuoteBean> convertQuoteList(ArrayList<Quote> quotes){
		ArrayList<QuoteBean> result = new ArrayList<QuoteBean>();
		for(Quote q : quotes){
			QuoteBean qb = q.toBean();
			result.add(qb);
		}
		return result;
	}
	
	public QuoteBean toBean(){
		QuoteBean q = new QuoteBean();
		q.setQuoteDate(this.quoteDate);
		q.setOpen(this.open);
		q.setHigh(this.high);
		q.setLow(this.low);
		q.setClose(this.close);
		q.setVolume(this.volume);
		q.setAdjRatio(this.adjRatio);
		return q;
		
	}
	
	/**
	 * This static method convert daily quotes to weekly quotes
	 * @param quotes
	 * @return an arraylist of quotes by weeks
	 */
	public static ArrayList<Quote> getQuotesByW(ArrayList<Quote> quotes){
		// week in Map is YYYYNN where NN is the week number
		HashMap<String, Quote> mapByWeek = new HashMap<String, Quote>();
		GregorianCalendar c = (GregorianCalendar) GregorianCalendar.getInstance();
		
		for(Quote q:quotes){
			String key;
			c.setTime(q.getQuoteDate());
			String year = (new Integer(c.YEAR)).toString();
			String week = (new Integer(c.WEEK_OF_YEAR)).toString();
			key=year+week;
			if(!mapByWeek.containsKey(key)){
				Quote weekQuote = new Quote(q.getQuoteDate(),q.getOpen(),q.getHigh(),q.getLow(),q.getClose(),q.getVolume(),q.getAdjRatio());
				mapByWeek.put(key, weekQuote);
			}else{
				Quote weekQuote = mapByWeek.get(key);
				if(q.getHigh()>weekQuote.getHigh())
					weekQuote.setHigh(q.getHigh());
				if(q.getLow()<weekQuote.getLow())
					weekQuote.setLow(q.getLow());
				weekQuote.setClose(q.getClose());
				weekQuote.setVolume(weekQuote.getVolume()+q.getVolume());
			}
		}
		Set<String> weeks = mapByWeek.keySet();
		
		ArrayList<Quote> result = new ArrayList<Quote>();
		for(String w:weeks){
			result.add(mapByWeek.get(w));
		}
		
		return result;
	}
	
	/**
	 * This static method convert daily quotes to monthly quotes
	 * @param quotes
	 * @return an arraylist of quotes by months
	 */
	public static ArrayList<Quote> getQuotesByM(ArrayList<Quote> quotes){
		// month in Map is YYYYNN where MM is the month number
		HashMap<String, Quote> mapByMonth = new HashMap<String, Quote>();
		GregorianCalendar c = (GregorianCalendar) GregorianCalendar.getInstance();
		
		for(Quote q:quotes){
			String key;
			c.setTime(q.getQuoteDate());
			String year = (new Integer(c.YEAR)).toString();
			String month = (new Integer(c.MONTH)).toString();
			key=year+month;
			if(!mapByMonth.containsKey(key)){
				Quote monthQuote = new Quote(q.getQuoteDate(),q.getOpen(),q.getHigh(),q.getLow(),q.getClose(),q.getVolume(),q.getAdjRatio());
				mapByMonth.put(key, monthQuote);
			}else{
				Quote weekQuote = mapByMonth.get(key);
				if(q.getHigh()>weekQuote.getHigh())
					weekQuote.setHigh(q.getHigh());
				if(q.getLow()<weekQuote.getLow())
					weekQuote.setLow(q.getLow());
				weekQuote.setClose(q.getClose());
				weekQuote.setVolume(weekQuote.getVolume()+q.getVolume());
			}
		}
		Set<String> months = mapByMonth.keySet();
		
		ArrayList<Quote> result = new ArrayList<Quote>();
		for(String m:months){
			result.add(mapByMonth.get(m));
		}
		
		return result;
	}
}
